package com.it135.citytraffic.task;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.it135.citytraffic.pojo.entity.ApiKey;
import com.it135.citytraffic.pojo.entity.Crossing;
import com.it135.citytraffic.pojo.entity.TrafficInfo;
import com.it135.citytraffic.service.IApiKeyService;
import com.it135.citytraffic.service.ICrossingService;
import com.it135.citytraffic.service.ITrafficInfoService;
import com.it135.citytraffic.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
 * 定时任务类，定时发送请求
 */
@Component
@Slf4j
public class monitorTask {


    private final IApiKeyService apiKeyService;

    private final ICrossingService crossingService;

    private final ITrafficInfoService trafficInfoService;
    private boolean isShutdown;
    private Integer errorAmount;
    //今日请求的次数
    private Integer amount;
    //失败次数

    @Value(value = "${static.times}")
    private Integer times;
    //    路口和key
    private List<ApiKey> keyList = new ArrayList<>();
    private List<Crossing> crossingList = new ArrayList<>();

    public monitorTask(IApiKeyService apiKeyService, ICrossingService crossingService, ITrafficInfoService trafficInfoService) {
        this.apiKeyService = apiKeyService;
        this.crossingService = crossingService;
        this.trafficInfoService = trafficInfoService;
        this.errorAmount = 0;
        this.amount = 0;
        this.isShutdown = false;
    }
//    location=&radius=1500&output=json&extensions=base&key=<用户的key>

    /**
     * 每天凌晨两点恢复
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void reSetup() {
        //将amount置为0
        amount = 0;
        keyList = apiKeyService.list();
    }

    /**
     * 每5分钟检查一次
     */
    @Scheduled(cron = "0 0/5 6-22  *  * ? ")
    public void tenMonitor() {
        keyList = apiKeyService.list();
        LambdaQueryWrapper<Crossing> eq = new LambdaQueryWrapper<Crossing>().eq(Crossing::getForbidden, 1);
        crossingList = crossingService.list(eq);
        if (!isShutdown) this.monitor();
    }


    public void monitor() {
        for (Crossing crossing : crossingList) {
            if (keyList.isEmpty()) {
                log.info("今日所有key的次数已经用完,总共发出请求数:{},失败次数:{},当前时间{}", amount, errorAmount, LocalDateTime.now());
                //终止请求
                this.isShutdown = true;
                break;
            }
            JSONObject jsonObject = sendRequest(crossing);
//            不成功的话就继续换key请求
            while (jsonObject.get("status").toString().equals("0")) {
                if (keyList.isEmpty()) break;
                else
                    keyList.remove(amount % keyList.size());
                amount++;
                errorAmount++;
                jsonObject = sendRequest(crossing);
            }
            amount++;
            Object trafficinfo = jsonObject.get("trafficinfo");
            log.info("请求数据:"+trafficinfo);
            if (trafficinfo == null){
                continue;
            }
//        获取evaluation
            jsonObject = JSONObject.parseObject(trafficinfo.toString());
            Object evaluation = jsonObject.get("evaluation");
            //            获取描述
            String description = jsonObject.get("description").toString();
//       获取evaluation里面的信息
            jsonObject = JSONObject.parseObject(evaluation.toString());
            String expedite = jsonObject.get("expedite").toString();
            String blocked = jsonObject.get("blocked").toString();
            String congested = jsonObject.get("congested").toString();
            String unknown = jsonObject.get("unknown").toString();
            String status = jsonObject.get("status").toString();
//            将信息保存到数据库
            TrafficInfo trafficInfo = new TrafficInfo();
            trafficInfo.setBlocked(blocked);
            trafficInfo.setExpedite(expedite);
            trafficInfo.setCongested(congested);
            trafficInfo.setUnknown(unknown);
            trafficInfo.setStatus(Integer.valueOf(status));
            trafficInfo.setDescription(description);
            trafficInfo.setCreateTime(LocalDateTime.now());
            trafficInfo.setName(crossing.getName());
            trafficInfo.setCrossingId(Math.toIntExact(crossing.getId()));
            String weatherStr = getWeatherStr(crossing.getCityCode());
            trafficInfo.setWeather(weatherStr);

            String tianqi = weatherStr.split(";")[0].split(":")[1];
            trafficInfo.setTianqi(tianqi);

            Integer temperature = Integer.parseInt(weatherStr.split(";")[1].split(":")[1]);
            trafficInfo.setTemperature(temperature);
            trafficInfoService.save(trafficInfo);
        }
    }

    /**
     * 发送请求查询路口交通情况
     *
     * @param crossing
     * @return
     */
    public JSONObject sendRequest(Crossing crossing) {
        //            设置查询参数
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("location", crossing.getPosition());
        paramMap.put("level", String.valueOf(crossing.getLevel()));
        if (!keyList.isEmpty()) {
            paramMap.put("key", keyList.get(amount % keyList.size()).getApiKey());
        }
        paramMap.put("output", "json");
        paramMap.put("extensions", "base");
        paramMap.put("radius", "1000");
//            发送请求
        String jsonStr = HttpClientUtil.doGet("https://restapi.amap.com/v3/traffic/status/circle?", paramMap);
        //解析返回结果
        return JSONObject.parseObject(jsonStr);
    }


    //    获取天气情况
    String getWeatherStr(String cityCode) {
        //            设置查询参数
        HashMap<String, String> paramMap = new HashMap<>();
        paramMap.put("output", "json");
        paramMap.put("extensions", "base");
        paramMap.put("city", cityCode);
        paramMap.put("key", keyList.get(amount % keyList.size()).getApiKey());
//            发送请求
        String jsonStr = HttpClientUtil.doGet("https://restapi.amap.com/v3/weather/weatherInfo?", paramMap);
//    解析结果
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        //            不成功的话就继续换key请求
        while (jsonObject.get("status").toString().equals("0")) {
            log.info("当前key失效:{}", keyList.get(amount % keyList.size()).getApiKey());
            keyList.remove(amount % keyList.size());
            amount++;
            errorAmount++;
            paramMap.put("key", keyList.get(amount % keyList.size()).getApiKey());
            jsonStr = HttpClientUtil.doGet("https://restapi.amap.com/v3/weather/weatherInfo?", paramMap);
            jsonObject = JSONObject.parseObject(jsonStr);
        }
// 获取名为livesJSON数组
        JSONArray livesArray = jsonObject.getJSONArray("lives");
        // 获取数组的第一个元素
        JSONObject livesJson = livesArray.getJSONObject(0);
//    获取
        String weather = livesJson.get("weather").toString();
        String temperature = livesJson.get("temperature").toString();
        String winddirection = livesJson.get("winddirection").toString();
        String windpower = livesJson.get("windpower").toString();
        return "天气:" + weather + ";温度:" + temperature + ";风向级别:" + winddirection + "风" + windpower;
    }
}

